package com.tianqu.tms.core.webservice.weichat.api.mq;

import java.util.Properties;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.SendResult;
import com.tianqu.tms.core.base.TxController;
import com.tianqu.tms.core.exception.TransactionException;
import com.tianqu.tms.core.util.MobileMessageUtils;
import com.tianqu.tms.core.util.StringUtil;
import com.tianqu.tms.dto.MessageHistoryDto;
import com.tianqu.tms.entity.TmsMessageEntity;

import net.chedaiban.wechat.api.mq.protobuf.Rpc.RpcMessage.Builder;


public class TransferMqProducer {

	protected Logger LOGGER = Logger.getLogger(getClass());

	static Producer producer = null;
	private static TransferMqProducer INSTANCE = new TransferMqProducer();

	private TransferMqProducer() {
	};

	public static TransferMqProducer getInstance() {
		return INSTANCE;
	}

	private void init() throws Exception {
		try {
			Properties producerProperties = new Properties();
			producerProperties.setProperty(PropertyKeyConst.ProducerId, MqConfig.TRANSFER_PRODUCER_ID);
			producerProperties.setProperty(PropertyKeyConst.AccessKey, MqConfig.ACCESS_KEY);
			producerProperties.setProperty(PropertyKeyConst.SecretKey, MqConfig.SECRET_KEY);
			producerProperties.setProperty(PropertyKeyConst.ONSAddr, MqConfig.ADDRESS);
			producer = (Producer) ONSFactory.createProducer(producerProperties);
			producer.start();
		} catch (Exception e) {
			producer = null;
			throw e;
		}
	}

	private SendResult send(String topic,String tag,byte[] body) throws Exception{
		try {
			if (producer == null) INSTANCE.init();
			return producer.send(new Message(topic, tag, body));
		} catch (Exception e) {
			LOGGER.error("failted to send mq message",e);
			return null;
		}
	}
	
	public SendResult send(Builder message,boolean isPersistence){
		
		TmsMessageEntity messageEntity = TmsMessageEntity.getInstance();
		TxController controller = TxController.getTxController();
		SendResult r = null;
		try {
			//
			r = send(MqConfig.TRANSFER_TOPIC, MqConfig.TAG,message.build().toByteArray());
			LOGGER.info("==>send mq[transfer]:"+message.getPayloadClass()+" id:"+r.getMessageId());
			//
			if(isPersistence){
				MessageHistoryDto dto = new MessageHistoryDto();
				controller.begin();
				//
				dto.setAction(TmsMessageEntity.ACTION_SEND);
				dto.setPayloadClass(message.getPayloadClass());
				dto.setPayloadData(message.getPayloadData().toByteArray());
				dto.setProtocol(TmsMessageEntity.PROTOCOL_PROTOBUF);
				if(r == null || StringUtil.isNullOrBlank(r.getMessageId())){
					 dto.setResult(TmsMessageEntity.RESULT_NG);
					 dto.setMessageId("");
				}else{ 
					dto.setMessageId(r.getMessageId());
					dto.setResult(TmsMessageEntity.RESULT_OK);
				}
				dto.setResultMessage("");
				dto.setType(TmsMessageEntity.TYPE_TMS);
				dto.setUpdateUserId(1);
				//
				messageEntity.insert(dto);
				controller.commit();
			}
		} catch (Exception e) {
			LOGGER.error("failted to send mq message",e);
			if(isPersistence){
				try {
					controller.rollback(); } catch (TransactionException e1) { LOGGER.error("failted to rollback db",e1);
				}
			}
		}
		//send mobile message
		if(r == null || "".equals(r.getMessageId())){
			String mqMessage = "faild to send mq[transfer],class:"+message.getPayloadClass();
			LOGGER.error(mqMessage);
			MobileMessageUtils.sendMobileMessage(mqMessage);
		}
		return r;
	}
	
	public void send(Builder message){
		send(message,true);
	}
	
	//tms to app
	public static void main(String[] args) {
		TransferMqProducer.getInstance();
	}
}
